﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InHD.model;
using System.Reflection;
using System.Data;
using InHD.utilities;

namespace InHD.dataaccess
{
    class PackageRepository
    {
        #region Fields
        List<Package> _packages;
        //For DB Utils
        private DBUltils _db;
        string[] _paramName;
        string[] _value;
        DBUltils.ParamType[] _paramType;
        #endregion // Fields

        #region Constructor

        /// <summary>
        /// Creates a new repository of CompanyInfos.
        /// </summary>
        public PackageRepository()
        {
            _packages = new List<Package>();
            this._db = new DBUltils();
            if (!_db.connectDB(Constants.Security.DefaultDBUser, Constants.Security.DefaultDBPassword))
                throw new ArgumentNullException(Constants.Messages.CannotConnectDB);
        }

        #endregion // Constructor

        #region Public Interface

        public event EventHandler<PackageAddedEventArgs> PackageAdded;

        public string AddPackge(Package package)
        {
            try
            {
                if (package == null)
                    throw new ArgumentNullException("package");

                package.PackageUNK = "Pac-" + Guid.NewGuid().ToString();

                //// Add new product into database
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                if (package.PackageUNK == null)
                    throw new ArgumentNullException("Null Unique key");
                _paramName = new string[]{"@packageUNK",
                                        "@quantity",
                                        "@salePrice",
                                        "@transactionUNK",
                                        "@productUNK",
                                        "@productCode",
                                        "@productName"};
                _paramType = new DBUltils.ParamType[]{DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Int,
                                                    DBUltils.ParamType.Real,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str
                                                    };
                _value = new string[]{package.PackageUNK,
                                    package.Quantity.ToString(),
                                    package.UnitPrice.ToString(),
                                    package.TransactionUNK,
                                    package.ProductUNK,
                                    package.SerialNo,
                                    package.ProductName
                                    };

                _db.queryDB("AddPackage", _paramName, _paramType, _value, DBUltils.QueryType.Insert);

                _packages.Add(package);
                if (this.PackageAdded != null)
                    this.PackageAdded(this, new PackageAddedEventArgs(package));
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Add package successfully!!!");
            return string.Empty;
        }

        public string EditPackage(Package package)
        {
            try
            {
                if (package == null)
                    throw new ArgumentNullException("package");

                for (int i = 0; i < this._packages.Count; i++)
                {
                    Package p = this._packages[i];
                    if (p.PackageUNK.Equals(package.PackageUNK))
                    {
                        p = package;
                        if (_db == null)
                            throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                        _paramName = new string[]{"@packageUNK",
                                        "@quantity",
                                        "@salePrice",
                                        "@transactionUNK",
                                        "@productUNK"};
                        _paramType = new DBUltils.ParamType[]{DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Int,
                                                    DBUltils.ParamType.Real,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str
                                                    };
                        _value = new string[]{package.PackageUNK,
                                    package.Quantity.ToString(),
                                    package.SalePrice.ToString(),
                                    package.TransactionUNK,
                                    package.ProductUNK
                                    };

                        _db.queryDB("UpdatePackage", _paramName, _paramType, _value, DBUltils.QueryType.Update);
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Edit package successfully!!!");
            return string.Empty;
        }

        public string DeletePackage(string UNK)
        {
            bool found = false;
            foreach (Package pack in this._packages)
            {
                if (pack.PackageUNK.Equals(UNK))
                {
                    this._packages.Remove(pack);
                    found = true;
                    break;
                }
            }
            if (!found)
                return "UNK is not exist";
            try
            {
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                if (UNK == null)
                    throw new ArgumentNullException("Null Unique key");
                _paramName = new string[] { "@packageUNK" };
                _paramType = new DBUltils.ParamType[] { DBUltils.ParamType.Str };
                _value = new string[] { UNK };

                _db.queryDB("DeletePackage", _paramName, _paramType, _value, DBUltils.QueryType.Delete);
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Delete Package successfully!!!");
            return string.Empty;
        }

        public List<Package> GetPackages()
        {
            return this._packages;
        }

        public List<Package> GetProductsWthSearchCriteria(string property, string criteria)
        {
            List<Package> tmpList = new List<Package>();
            foreach (Package pro in this._packages)
            {
                Type t = pro.GetType();
                PropertyInfo p = t.GetProperty(property);
                string valueOfProperty = (string)p.GetValue(pro, null);
                if (valueOfProperty.Contains(criteria))
                {
                    tmpList.Add(pro);
                }
            }

            return tmpList;
        }

        #endregion // Public Interface

        public List<Package> GetPackgesByTransaction(string TransactionUNK)
        {
            DataSet ds;
            List<Package> packages = new List<Package>();
            if (_db == null)
                return null;
            if (TransactionUNK == null)
                return null;
            _paramName = new string[] { "@transactionUNK" };
            _paramType = new DBUltils.ParamType[] { DBUltils.ParamType.Str };
            _value = new string[] { TransactionUNK };

            ds = _db.queryDB("GetPackgesByTransaction", _paramName, _paramType, _value, DBUltils.QueryType.Select);
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                Package pack = Package.CreatePackageInfo(Convert.ToString(dr["packageUNK"]),
                                                            Convert.ToInt16(dr["quantity"]),
                                                            Convert.ToDouble(dr["salePrice"]),
                                                            Convert.ToString(dr["transactionUNK"]),
                                                            Convert.ToString(dr["productUNK"]),
                                                            Convert.ToString(dr["productName"]),
                                                            Convert.ToString(dr["productCode"])
                                                        );
                packages.Add(pack);
            }
            return packages;
        }
    }
}
